from .api import default
from .util import join_url


class Resource(object):
    def __str__(self):
        return self.__data__.__str__()

    def __repr__(self):
        return self.__data__.__str__()

    def __getattr__(self, name):
        try:
            super(Resource, self).__getattribute__(name)
        except AttributeError:
            return self.__data__.get(name)

    def __setattr__(self, name, value):
        try:
            # Handle attributes(error, header, request_id)
            super(Resource, self).__getattribute__(name)
            super(Resource, self).__setattr__(name, value)
        except AttributeError:
            self.__data__[name] = value

    def __contains__(self, item):
        return item in self.__data__

    def __getitem__(self, key):
        return self.__data__[key]

    def __setitem__(self, key, value):
        self.__data__[key] = self.convert(key, value)

    def __init__(self, new_attributes={}, api=None):
        self.__dict__['api'] = api or default()
        super(Resource, self).__setattr__('__data__', {})
        super(Resource, self).__setattr__('message', None)
        super(Resource, self).__setattr__('headers', {})
        super(Resource, self).__setattr__('header', {})
        super(Resource, self).__setattr__('request_id', None)
        self.success = not new_attributes.get('error')
        self.merge(new_attributes)

    def merge(self, new_attributes):
        """Merge new attributes e.g. response from a post to Resource
        """
        for k, v in new_attributes.items():
            setattr(self, k, v)


class Find(Resource):
    @classmethod
    def find(cls, resource_id, api=None):
        api = api or default()
        url = join_url(cls.path, resource_id)
        return cls(api.get(url, None), api)


class Create(Resource):
    @classmethod
    def create(cls, data, api=None):
        api = api or default()

        attributes = api.post(cls.path, data)
        return cls(attributes)


class List(Resource):
    list_class = Resource

    @classmethod
    def all(cls, attributes=None, api=None):
        api = api or default()
        response = None
        try:
            response = api.get(cls.path, attributes)
            return cls.list_class(response, api=api)
        except AttributeError as e:
            # To handle the case when response is JSON Array
            if isinstance(response, list):
                new_resp = [cls.list_class(elem, api=api) for elem in response]
                return new_resp
